package de.slothsoft.commons.swing.databinding;

import java.lang.reflect.Method;

public final class PropertyUtil {

	public static final String GETTER = "get";
	public static final String IS_GETTER = "is";
	public static final String SETTER = "set";

	public static final <T> void invokeSetter(final Object model,
			final String property, T value) throws DataBindingException {
		if (value == null) {
			throw new DataBindingException(
					"If value is null, you have to define the class!");
		}
		invokeSetter(model, property, value, value.getClass());
	}

	public static final void invokeSetter(final Object model,
			final String property, Object value, Class<?> valueClass)
			throws DataBindingException {
		try {
			Method setter = getSetter(model.getClass(), property, valueClass);
			setter.invoke(model, value);
		} catch (Exception e) {
			throw new DataBindingException(e);
		}
	}

	public static final Method getSetter(final Class<?> clazz,
			final String property, Class<?> valueClass)
			throws DataBindingException {
		try {
			return clazz.getMethod(SETTER + property, valueClass);
		} catch (Exception e) {
			throw new DataBindingException(e);
		}
	}

	@SuppressWarnings("unchecked")
	public static final <T> T invokeGetter(final Object model,
			final String property) throws DataBindingException {
		try {
			Method getter = getGetter(model.getClass(), property);
			return (T) getter.invoke(model);
		} catch (Exception e) {
			throw new DataBindingException(e);
		}
	}

	public static final Method getGetter(final Class<?> clazz,
			final String property) throws DataBindingException {
		try {
			try {
				return clazz.getMethod(IS_GETTER + property);
			} catch (Exception e) {
				// if this did not work, the getter might not be isBoolean
				return clazz.getMethod(GETTER + property);
			}
		} catch (Exception e) {
			throw new DataBindingException(e);
		}
	}

	private PropertyUtil() {
		// *hides*
	}
}
